// console.log(this); // window

// let o = { sing: "sing" };
// // 如何将this指向o呢？
// let obj = {
//   name: "刘德华",
//   say: function (...args) {
//     console.log(args);
//     console.log(this); // this -> o
//   },
// };
// obj.say.call(o, o.sing, 1, 2, 3);

// 自己实现一个 call 方法
// 思路：
// 1.在 Function.prototype 上定义一个 myCall 方法，并且obj.say调用自定义的 myCall 方法
// 2.接收第一个参数，就是传递进来要硬绑定的新对象
// 3.在新对象内部创建一个 fn 函数，将 当前 this 赋值给 fn 函数（当前this是obj.say）
// 4.调用新对象中的 fn 函数执行（即调用obj.say执行）
// 5.完成后将新对象中的 fn 函数删除（避免占用内存）
// Function.prototype.myCall = function (context, ...args) {
//   console.log(this); // this -> obj.say
//   console.log(args); // 拿到参数做些什么
//   context.fn = this;
//   context.fn();
//   delete context.fn;
// };
// let o = { sing: "sing" };
// // 如何将this指向o呢？
// let obj = {
//   name: "刘德华",
//   say: function () {
//     console.log(this); // this -> o
//   },
// };
// obj.say.myCall(o, o.sing, 1, 2, 3);

// 优化
Function.prototype.myCall = function (context, ...args) {
  console.log(this); // this -> obj.say
  context = context ? context : window; // 参数兜底处理
  context.fn = this;
  context.fn(...args);
  delete context.fn;
};
let o = { sing: "sing" };
// 如何将this指向o呢？
let obj = {
  name: "刘德华",
  say: function (...args) {
    console.log(args); // 拿到参数做些什么
    console.log(this); // this -> o
  },
};
obj.say.myCall(null, o.sing, 1, 2, 3);
